/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.diplomka.datalayer.daoimpl;

import cz.muni.fi.diplomka.datalayer.dao.MessageDao;
import cz.muni.fi.diplomka.datalayer.entity.MessageEntity;
import cz.muni.fi.diplomka.datalayer.util.DbConnector;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Jakub Kutil
 */
public class MessageDaoImpl implements MessageDao {

    private Connection con = null;
    private PreparedStatement ps = null;
    private ResultSet rs = null;

    public MessageDaoImpl() {
    }

    @Override
    public void addMessage(MessageEntity messageEntity) {
        if (messageEntity == null) {
            throw new IllegalArgumentException("MessageEntity can not be null");
        }

        try {
            con = DbConnector.getDBConnection();
            String insert = "INSERT INTO message"
                    + "(id_from, id_to, subject, body, time, unread) VALUES"
                    + "(?,?,?,?,?,?)";
            ps = con.prepareStatement(insert);


            ps.setLong(1, messageEntity.getIdFrom());
            ps.setLong(2, messageEntity.getIdTo());
            ps.setString(3, messageEntity.getSubject());
            ps.setString(4, messageEntity.getBody());
            ps.setTimestamp(5, messageEntity.getTime());
            ps.setBoolean(6, true);

            ps.executeUpdate();

            rs = ps.getGeneratedKeys();
            rs.next();


        } catch (SQLException ex) {
            Logger.getLogger(MessageDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            DbConnector.closeConnection(rs, ps, con);
        }
    }

    @Override
    public void editMessage(MessageEntity messageEntity) {
        if (messageEntity == null) {
            throw new IllegalArgumentException("MessageEntity can not be null");
        }
        try {
            con = DbConnector.getDBConnection();
            String update = "UPDATE message SET id_from=?, id_to=?, subject=?, body=?, time=?, unread=? WHERE id= ?";

            ps = con.prepareStatement(update);

            ps.setLong(1, messageEntity.getIdFrom());
            ps.setLong(2, messageEntity.getIdTo());
            ps.setString(3, messageEntity.getSubject());
            ps.setString(4, messageEntity.getBody());
            ps.setTimestamp(5, messageEntity.getTime());
            ps.setBoolean(6, messageEntity.isUnread());
            ps.setLong(7, messageEntity.getId());

            ps.executeUpdate();
        } catch (SQLException ex) {
            Logger.getLogger(MessageDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            DbConnector.closeConnection(rs, ps, con);
        }
    }

    @Override
    public void deleteMessage(Long id) {
        if (id == null) {
            throw new IllegalArgumentException("ID can not be null");
        }
        try {
            con = DbConnector.getDBConnection();
            String delete = "DELETE FROM message WHERE id=?";

            ps = con.prepareStatement(delete);

            ps.setLong(1, id);

            ps.executeUpdate();
        } catch (SQLException ex) {
            Logger.getLogger(MessageDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            DbConnector.closeConnection(rs, ps, con);
        }
    }

    @Override
    public List<MessageEntity> getAllReceivedMessagesOfPlayer(Long playerId) {
        List<MessageEntity> recievedMessagesList = new ArrayList<MessageEntity>();

        try {
            con = DbConnector.getDBConnection();
            String getAllReceivedMessagesOfPlayer = "SELECT * FROM message WHERE id_to=?";

            ps = con.prepareStatement(getAllReceivedMessagesOfPlayer);
            ps.setLong(1, playerId);

            rs = ps.executeQuery();

            while (rs.next()) {
                MessageEntity messageEntity = new MessageEntity();
                messageEntity.setId(rs.getLong("id"));
                messageEntity.setIdFrom(rs.getLong("id_from"));
                messageEntity.setIdTo(rs.getLong("id_to"));
                messageEntity.setSubject(rs.getString("subject"));
                messageEntity.setBody(rs.getString("body"));
                messageEntity.setTime(rs.getTimestamp("time"));
                messageEntity.setUnread(rs.getBoolean("unread"));
                recievedMessagesList.add(messageEntity);

            }
        } catch (Exception ex) {
            Logger.getLogger(MessageDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            DbConnector.closeConnection(rs, ps, con);
        }
        return recievedMessagesList;
    }

    @Override
    public List<MessageEntity> getAllSentMessagesOfPlayer(Long playerId) {
        List<MessageEntity> sentMessagesList = new ArrayList<MessageEntity>();

        try {
            con = DbConnector.getDBConnection();
            String getAllSentMessagesOfPlayer = "SELECT * FROM message WHERE id_from=?";

            ps = con.prepareStatement(getAllSentMessagesOfPlayer);
            ps.setLong(1, playerId);

            rs = ps.executeQuery();

            while (rs.next()) {
                MessageEntity messageEntity = new MessageEntity();
                messageEntity.setId(rs.getLong("id"));
                messageEntity.setIdFrom(rs.getLong("id_from"));
                messageEntity.setIdTo(rs.getLong("id_to"));
                messageEntity.setSubject(rs.getString("subject"));
                messageEntity.setBody(rs.getString("body"));
                messageEntity.setTime(rs.getTimestamp("time"));
                messageEntity.setUnread(rs.getBoolean("unread"));
                sentMessagesList.add(messageEntity);

            }
        } catch (SQLException ex) {
            Logger.getLogger(MessageDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
            } catch (Exception e) { /* ignored */ }

            try {
                if (con != null) {
                    con.close();
                }
            } catch (Exception e) { /* ignored */ }
        }
        return sentMessagesList;
    }

    @Override
    public int getCountOfUnreadReceivedMessagesOfPlayer(Long playerId) {
        int count = 0;
        try {
            con = DbConnector.getDBConnection();
            String getCountOfUnreadReceivedMessagesOfPlayer = "SELECT COUNT(*) FROM message WHERE id_to=? AND unread=TRUE";

            ps = con.prepareStatement(getCountOfUnreadReceivedMessagesOfPlayer);
            ps.setLong(1, playerId);

            rs = ps.executeQuery();

            while (rs.next()) {
                count = rs.getInt(1);
            }
        } catch (SQLException ex) {
            Logger.getLogger(MessageDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            DbConnector.closeConnection(rs, ps, con);
        }
        return count;
    }

    @Override
    public MessageEntity findMessage(Long id) {
        if (id == null) {
            throw new IllegalArgumentException("ID can not be null");
        }
        MessageEntity messageEntity = new MessageEntity();
        try {
            con = DbConnector.getDBConnection();
            String findMessage = "SELECT * FROM message WHERE id=?";

            ps = con.prepareStatement(findMessage);

            ps.setLong(1, id);

            rs = ps.executeQuery();
            rs.next();

            messageEntity.setId(rs.getLong("id"));
            messageEntity.setIdFrom(rs.getLong("id_from"));
            messageEntity.setIdTo(rs.getLong("id_to"));
            messageEntity.setSubject(rs.getString("subject"));
            messageEntity.setBody(rs.getString("body"));
            messageEntity.setTime(rs.getTimestamp("time"));
            messageEntity.setUnread(rs.getBoolean("unread"));

        } catch (SQLException ex) {
            Logger.getLogger(MessageDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            DbConnector.closeConnection(rs, ps, con);
        }
        return messageEntity;
    }
}
